<template>
<el-dialog class="multiple-dialog" :append-to-body="true" :title="data.title" :visible.sync="data.show" width="860px" :close-on-click-modal="false">
    <el-input clearable placeholder="输入关键字搜索列，包含关键字即可" suffix-icon="el-icon-search" v-model="searchCondition"></el-input>
    <div class="wrap">
        <div class="left-wrap">
            <div class="wrap-header">
                <el-checkbox v-model="checkType.all" :indeterminate="checkTypeIndeterminate.all" @change="handleCheckAll($event)">全选
                </el-checkbox>
            </div>
            <div class="scroll-bar">
                <el-collapse v-model="topCollapse" v-if="Object.keys(leftTableData).length>0">
                    <el-collapse-item :name="`${key}`" :title="key" v-for="(item, key) in leftTableData" :key="key">
                        <template slot="title">
                            <el-checkbox :indeterminate="checkTypeIndeterminate[key]" v-model="checkType[key]" @change="handleCheckAll($event, key)">{{key}}</el-checkbox>
                        </template>
                        <el-checkbox v-model="leftTableData[key][subKey]" class="my-checkbox" @change="handleCheckChange($event, key)" v-for="(subItem, subKey) in leftTableData[key]" :key="subKey">{{subKey}}
                        </el-checkbox>
                    </el-collapse-item>
                </el-collapse>
                <div v-else class="empty-box">暂无数据</div>
            </div>
        </div>
        <div class="right-wrap">
            <div class="wrap-header">
                <span>已选</span>
                <el-radio-group size="mini" v-model="isEdit">
                    <el-radio-button :label="false">列表</el-radio-button>
                    <el-radio-button :label="true">编辑</el-radio-button>
                </el-radio-group>
            </div>
            <div v-if="!isEdit" class="scroll-bar">
                <el-table size="mini" :data="selectedTableData">
                    <el-table-column align="center" width="55">
                        <template slot="header">
                            <i class="el-icon-delete" @click="removeRow()"></i>
                        </template>
                        <template slot-scope="scope">
                            <i class="el-icon-delete" @click="removeRow(scope.row.name)"></i>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="name" label="字段" show-overflow-tooltip></el-table-column>
                    <el-table-column align="center" prop="type" label="类型" show-overflow-tooltip></el-table-column>
                </el-table>
            </div>
            <el-input v-else :rows="4" type="textarea" placeholder="请编辑" @blur="handleChangeEdit" v-model="editVal"></el-input>
        </div>
    </div>
    <span slot="footer" class="dialog-footer">
        <el-button @click="data.show=false">取 消</el-button>
        <el-button type="primary" v-preventReClick="2000" @click="handleSave">确 定</el-button>
    </span>
</el-dialog>
</template>

<script>
export default {
    name: 'MultipleSelect',
    props: {
        value: {
            type: String
        },
        data: {
            type: Object,
            required: true
        }
    },
    data () {
        return {
            defaultVal: '',
            searchCondition: '',
            leftTableData: {},
            allTableData: {},
            isEdit: false,
            topCollapse: [],
            editVal: '',
            checkType: {
                all: false
            },
            checkTypeIndeterminate: {
                all: false
            },
            allCols: {}
        }
    },
    computed: {
        selectedTableData () {
            let selectedCols = []
            if (this.$isEmpty(this.leftTableData) && this.$isEmpty(this.defaultVal)) {
                return selectedCols
            }
            let values = this.$isEmpty(this.defaultVal) ? [] : this.defaultVal.replace(new RegExp(' ', 'g'), '').split(',')
            for (let tp in this.leftTableData) {
                for (let col in this.leftTableData[tp]) {
                    this.$set(this.allTableData[tp], col, this.leftTableData[tp][col])
                }
            }
            for (let tp in this.allTableData) {
                for (let col in this.allTableData[tp]) {
                    if (this.allTableData[tp][col]) {
                        selectedCols.push({
                            name: col,
                            type: tp
                        })
                    }
                }
            }
            for (let val of values) {
                if (this.allCols.hasOwnProperty(val)) {
                    if (this.allCols[val] === '--') {
                        selectedCols.push({
                            name: val,
                            type: '--'
                        })
                    }
                } else {
                    this.$set(this.allCols, val, '--')
                    selectedCols.push({
                        name: val,
                        type: '--'
                    })
                }
            }
            return selectedCols
        }
    },
    created () {
        this.defaultVal = this.value
        this.editVal = this.value
        this.initTableData()
    },
    methods: {
        initTableData () {
            let leftTableData = {}
            let allTableData = {}
            this.editVal = this.editVal.replace(/[\r\n]/g, '')
            this.editVal = Array.from(new Set(this.editVal.split(','))).join(',')
            this.defaultVal = this.defaultVal.replace(/[\r\n]/g, '')
            this.defaultVal = Array.from(new Set(this.defaultVal.split(','))).join(',')
            let values = this.$isEmpty(this.editVal) ? [] : this.editVal.replace(new RegExp(' ', 'g'), '').split(',')
            this.topCollapse = []
            // 将列格式化为左边表格需要的格式
            let arr = this.data.data
            let flag = this.data.isNumber
            arr.forEach(colsItem => {
                const {
                    name,
                    type
                } = colsItem
                if (flag && !['Long', 'Short', 'Double', 'Integer', 'Float'].includes(type)) {
                    return false
                }
                if (name.includes(this.searchCondition)) {
                    if (leftTableData.hasOwnProperty(type)) {
                        this.$set(leftTableData[type], name, values.indexOf(name) > -1)
                    } else {
                        this.$set(this.checkType, type, false)
                        this.$set(this.checkTypeIndeterminate, type, false)
                        this.topCollapse.push(type)
                        this.$set(leftTableData, type, {
                            [name]: values.indexOf(name) > -1
                        })
                    }
                    this.$set(this.allCols, name, type)
                }
                if (allTableData.hasOwnProperty(type)) {
                    this.$set(allTableData[type], name, values.indexOf(name) > -1)
                } else {
                    this.$set(allTableData, type, {
                        [name]: values.indexOf(name) > -1
                    })
                }
            })
            // 将编辑区中不存在类型的加入到列中
            values.forEach((item) => {
                if (!this.allCols.hasOwnProperty(item)) {
                    this.$set(this.allCols, item, '--')
                }
            })
            this.leftTableData = leftTableData
            this.allTableData = allTableData
            this.checkSelected()
        },
        handleSave () {
            this.$emit('save', 'multiple', this.editVal)
        },
        removeRow (name) {
            if (name) {
                let values = this.editVal.replace(new RegExp(' ', 'g'), '').split(',')
                if (this.allCols[name] === '--') {
                    this.editVal = values.filter(item => item === name).join(',')
                    this.defaultVal = values.filter(item => item !== name).join(',')
                } else {
                    this.leftTableData[this.allCols[name]][name] = false
                }
            } else {
                let newLeftTableData = JSON.parse(JSON.stringify(this.leftTableData))
                for (let tp in newLeftTableData) {
                    for (let col in newLeftTableData[tp]) {
                        newLeftTableData[tp][col] = false
                    }
                }
                this.leftTableData = newLeftTableData
                this.editVal = ''
                this.defaultVal = ''
            }
            this.checkSelected()
        },
        handleChangeEdit () {
            this.editVal = this.editVal.trim()
            this.$emit('input', this.editVal)
        },
        handleCheckAll ($event, type) {
            if (type) {
                let newType = JSON.parse(JSON.stringify(this.leftTableData[type]))
                for (let name in newType) {
                    newType[name] = $event
                }
                this.$set(this.leftTableData, type, newType)
            } else {
                let newLeftTableData = JSON.parse(JSON.stringify(this.leftTableData))
                // 设置字段选中
                for (let tp in newLeftTableData) {
                    for (let col in newLeftTableData[tp]) {
                        newLeftTableData[tp][col] = $event
                    }
                }
                this.leftTableData = newLeftTableData
                this.checkSelected()
            }
        },
        handleCheckChange ($event, tp) {
            this.checkSelected()
        },
        checkSelected () {
            let total = {
                all: 0
            }
            let typeSelected = {
                all: 0
            }
            for (let tp in this.leftTableData) {
                for (let col in this.leftTableData[tp]) {
                    if (this.leftTableData[tp][col]) {
                        typeSelected.all++
                        if (typeSelected[tp]) {
                            typeSelected[tp]++
                        } else {
                            typeSelected[tp] = 1
                        }
                    }
                    if (total[tp]) {
                        total[tp]++
                    } else {
                        total[tp] = 1
                    }
                    total.all++
                }
            }
            for (let tp in this.checkType) {
                this.$set(this.checkType, tp, typeSelected[tp] > 0 ? typeSelected[tp] === total[tp] : false)
            }
            for (let tp in this.checkTypeIndeterminate) {
                this.$set(this.checkTypeIndeterminate, tp, typeSelected[tp] > 0 ? typeSelected[tp] !== total[tp] : false)
            }
        }
    },
    watch: {
        searchCondition (val) {
            this.initTableData()
        },
        value (val) {
            this.editVal = val
            this.defaultVal = val
            this.initTableData()
        },
        selectedTableData (val) {
            if (this.$isEmpty(val)) {
                this.$emit('input', '')
                return
            }
            let newVal = ''
            for (let item of val) {
                newVal += item.name + ','
            }
            newVal = newVal.length > 0 ? newVal.substring(0, newVal.length - 1) : ''
            this.$emit('input', newVal)
        }
    }
}
</script>

<style lang="less">
.multiple-dialog {
    .wrap {
        height: 500px;
        display: flex;

        .empty-box {
            width: 100%;
            height: 95px;
            border: 1px solid #ebeef5;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            color: #909399;
        }

        .scroll-bar {
            max-height: 450px;
        }

        .el-textarea {
            height: 100%;
        }

        .el-textarea__inner {
            height: calc(100% - 50px);
            line-height: initial;
        }

        .el-icon-delete {
            cursor: pointer;
            font-size: 18px;
        }

        .el-collapse-item__content {
            padding: 0;
            display: flex;
            flex-direction: column;
        }

        .el-collapse,
        .table {
            border: 1px solid #ebeef5;
        }

        .el-collapse-item__header {
            background: #e3f4ff;
            height: 31px;
            line-height: 31px;
            padding-left: 10px;
        }

        .my-checkbox {
            border-top: 1px solid #ebeef5;
            line-height: 31px;
            margin: 0;
            padding-left: 20px;
        }

        .left-wrap {
            width: 50%;
            float: left;
            margin-right: 10px;
        }

        .right-wrap {
            width: 50%;
            float: right;
            margin-left: 10px;
        }

        .wrap-header {
            height: 50px;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .el-icon-delete {
            color: #909399;
        }
    }
}
</style>
